home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / HDX_BACK / HDXPCH / HDX.BAK < prev    next >
Encoding:
Text File  |  2001-02-09  |  26.2 KB  |  1,062 lines

  1. /* hdx.c */
  2.  
  3. /*
  4.  * Atari Hard Disk Installation Utility
  5.  * Copyright 1988 Atari Corp.
  6.  *
  7.  * Associated files
  8.  *    hdx.rsc        resource file
  9.  *    wincap        hard disk database (text file)
  10.  *
  11.  *    hdx.h        object tree definitions
  12.  *    defs.h        constant definitions
  13.  *    part.h        ST structure definitions
  14.  *    ipart.h        IBM structure definitions
  15.  *
  16.  *    hdx.c        top level, user interface (this file)
  17.  *    epart.c        edit partition sizes
  18.  *    fmt.c        disk formatting
  19.  *    part.c        partition reading/writing
  20.  *    sect.c        sector reading, writing, zeroing
  21.  *    string.c    string functions (matching, concat, ...)
  22.  *    assist.c    markbad(), zero()
  23.  *    wincap.c    hard disk parameter / partition size database
  24.  *    st.c        random ST functions (delay, reboot, ...)
  25.  *
  26.  *----
  27.  * 8-Nov-1988  jye. change and add some codes so that can be used for extended
  28.  *                    and big partition.
  29.  * 13-Jun-1989 jye. Change and add some codes so that HDX can be deal with
  30.  *                    acsi and scsi drives.
  31.  * 22-Jan-1990 jye. Change the HDX so that we don't have to put a informations
  32.  *                    of a drive into the Wincap file.
  33.  * 13-Mar-1990 jye. change the HDX to a genetic one so that the user don't
  34.  *                    need know what kind of drive.
  35.  * 20-Jul-1990 jye. change the interface about the unit select. In the new 
  36.  *                    interface, user tells the type of drive is acsi or scsi,
  37.  *                    then selects unit.
  38.  * 01-Aug-1990 jye. Change hard disk size request from mdsence to readcap.
  39.  * 25-Jul-1991 jye. Change the Hdx so that can be used for IDE-AT drive.
  40.  * 11-Nov-1991 jye. change the hdx so that can got the hard disk size from
  41.  *                    page 0, or 3, or 4, or from the wincap. For the SCSI drive,
  42.  *                    getting the disk size from wincap or readcap.
  43.  * 7-Jul-1992  jye. Change the hdx so that can be used for the sparrow scsi.
  44.  * Feb-3-1993  jye. Fixed a bug which is when format a hard disk with no wincap
  45.  *                    file, then the HDX will bomb out. Now, you can still format
  46.  *                    the hard disk without the wincap, because the wincap file
  47.  *                    is used when HDX can't get the hard disk's informations.
  48.  * Apr-9-1993  jye.    To fixed a problem for the Conner CP2088 drive, which HDX
  49.  *                    can't Markbad it in Format, because this kind of drive has
  50.  *                    the different values of head, cylinder, and spt between the
  51.  *                    physical and logical parameters, so I added a inqury() call
  52.  *                    right after the 'fmtunt()' in 'dodiform()' to up date the
  53.  *                    table, because 'fmtunt()' changes the physical parameters 
  54.  *                    to the logical parameters.
  55.  */
  56.  
  57. #include "obdefs.h"
  58. #include "gemdefs.h"
  59. #include "osbind.h"
  60. #include "mydefs.h"
  61. #include "part.h"
  62. #include "bsl.h"
  63. #include "hdxpch.h"
  64. #include "ipart.h"
  65. #include "addr.h"
  66. #include "myerror.h"
  67.  
  68. #define MFM 17
  69.  
  70. extern char sbuf[];
  71. extern int rebootp;
  72. extern int yesscan;
  73. extern long disksiz;
  74. extern long ratio;
  75. extern int typedev;
  76. extern int typedrv;
  77. extern int prevnpart;
  78. extern int atexst;        /* set for AT drive exist */
  79. extern int floptical;    /* set if it's a floptical drive */
  80. extern int tformat;        /* 1: called by Format */
  81.  
  82. /* Globals */
  83. BYTE *bsl;            /* bad sector list */
  84. long bslsiz;            /* num sectors BSL occupies */
  85. SECTOR badbuf[WARNBADSECTS];    /* bad sectors buffer */
  86. int rebootp = 0;    /* 1: must reboot (not return to desktop) */
  87. int tformat;            /* TRUE: just formatted disk */
  88. int running;        /* 1: continue evnt_multi() loop */
  89. char sbuf[512];        /* error message buffer */
  90. long extsiz;        /* the size of extened partition */
  91. long ostack;        /* old stack pointer */
  92. long bps;            /* bytes per sector */
  93. int npart;            /* number of partition */
  94. int ext;            /* the index of extended partition */
  95. int extend;            /* the index of end extended partition */
  96. int showmany;        /* the flag that show the too much device alert box */
  97. char ttscsi;        /* SCSI hard disk drive */
  98. char spscsixst;        /* set for sparrow scsi drive exist */
  99. int noacsi;            /* set for no ACSI dirve in the system */
  100. int needscan;        /* TRUE: if info in the LOGMAP update */
  101. int noinfo=1;            /* 1: no informations in the wincap */
  102. int athead;            /* the # of data heads on the AT drive */
  103. int atcyl;            /* the # of cylinders on the AT drive */
  104. int atspt;            /* the # of sectors per track on the AT drive */
  105. int ok2draw;        /* go ahead to draw the change part of dialog box */
  106. int ndevs;            /* the # of devices */
  107. char *drvid[] ={    /* for the id of the drives */
  108.     "123456789012345678901234567",
  109.     "123456789012345678901234567",
  110.     "123456789012345678901234567",
  111.     "123456789012345678901234567",
  112.     "123456789012345678901234567",
  113.     "123456789012345678901234567",
  114.     "123456789012345678901234567",
  115.     "123456789012345678901234567",
  116.     "123456789012345678901234567",
  117.     "123456789012345678901234567",
  118.     "123456789012345678901234567",
  119.     "123456789012345678901234567",
  120.     "123456789012345678901234567",
  121.     "123456789012345678901234567",
  122.     "123456789012345678901234567",
  123.     "123456789012345678901234567",
  124.     "123456789012345678901234567",
  125.     "Identification unavaliable",
  126.     "Not responding",
  127.     "ACSI 0",        /* index is 19 */
  128.     "ACSI 1",
  129.     "ACSI 2",
  130.     "ACSI 3",
  131.     "ACSI 4",
  132.     "ACSI 5",
  133.     "ACSI 6",
  134.     "ACSI 7",
  135.     "SCSI 0",        /* index is 27 */
  136.     "SCSI 1",
  137.     "SCSI 2",
  138.     "SCSI 3",
  139.     "SCSI 4",
  140.     "SCSI 5",
  141.     "SCSI 6",
  142.     "SCSI 7",
  143.     "IDE 0",            /* index is 35 */
  144.     " "
  145. };
  146.  
  147. DEVSET devid[17];
  148.  
  149. /*  Logical-to-dev+partition mapping table. */
  150. extern int nlogdevs;        /* #logical devs found */
  151. extern LOGMAP logmap[];        /* logical dev map */
  152. extern int livedevs[];        /* live physical dev flag */
  153. extern int idevs[];            /* the devise have a id */
  154. extern char cachexst;        /* 0: no cache. 1: with cache */
  155.  
  156. /* Partition related variables */
  157. long mxpsiz = MAXPSIZ;
  158.  
  159. /* AES (windows and messages) related variables */
  160. int gl_hchar;        /* height of system font (pixels) */
  161. int gl_wchar;        /* width of system font (pixels) */
  162. int gl_wbox;        /* width of box able to hold system font */
  163. int gl_hbox;        /* height of box able to hold system font */
  164.  
  165. int phys_handle;    /* physical workstation handle */
  166. int handle;        /* virtual workstation handle */
  167. int wi_handle;        /* window handle */
  168.  
  169. int formw, formh, sx, sy, lx, ly;    /* dialogue box dimensions */
  170. int xdesk, ydesk, hdesk, wdesk;        /* window X, Y, width, height */
  171. int xwork, ywork, hwork, wwork;        /* desktop and work areas */
  172.  
  173. int msgbuff[8];        /* event message buffer */
  174. int keycode;        /* keycode returned by event-keyboard */
  175. int mx, my;        /* mouse x and y pos. */
  176. int butdown;        /* button state tested for, UP/DOWN */
  177. int ret;        /* dummy return variable */
  178. int pnf;        /* 1: partition or format; 0: zero or markbad */
  179. int hidden;        /* current state of cursor */
  180. int contrl[12];
  181. int intin[128];
  182. int ptsin[128];
  183. int intout[128];
  184. int ptsout[128];    /* storage wasted for idiotic bindings */
  185. int work_in[11];    /* Input to GSX parameter array */
  186. int work_out[57];    /* Output from GSX parameter array */
  187. int pxyarray[10];    /* input point array */
  188. int blitxst;        /* the flag for check the BLiTTER */
  189.  
  190. /*
  191.  * Top level;
  192.  * we get control from the desktop.
  193.  */
  194. main()
  195. {
  196.     pnf = 0;        /* set the flag to it isn't partition yet */
  197.     appl_init();
  198.     phys_handle=graf_handle(&gl_wchar, &gl_hchar, &gl_wbox, &gl_hbox);
  199.     wind_get(0, WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk);
  200.     open_vwork();
  201.     wi_handle=wind_create(0x0040&0x0080, xdesk, ydesk, wdesk, hdesk);
  202.  
  203.     hidden = FALSE;
  204.     butdown = TRUE;
  205.  
  206.     /* doing a checking see if the cache in the system */
  207.     cachexst = (char) chkcache();
  208.  
  209.     /* check the existence of the BLiTTER */
  210.     blitxst = chkblit();
  211.  
  212.     if (!rsrc_load(RESOURCEFILE)) {
  213.     errs("[2][|", RESOURCEFILE, "][ EXIT ]");
  214.     goto punt;
  215.     }
  216.  
  217.     
  218.     /* Get all addresses of dialogues from resource file */
  219.     if (getalladdr() != OK) {
  220.     errs("[2][|", RESOURCEFILE, "][ EXIT ]");
  221.     goto punt;
  222.     }
  223.  
  224.  
  225.     needscan = TRUE;
  226.  
  227. redomul:
  228.     ARROW_MOUSE;
  229.  
  230.     /* display menu bar */
  231.     menu_bar(menuobj, 1);
  232.  
  233.     running = TRUE;
  234.     while (running) {
  235.         domulti();
  236.     }
  237.  
  238.     /*
  239.      * If nothing has been done to the hard disks
  240.      * then just get out, back to the desktop.
  241.      * Otherwise reboot the system.
  242.      */
  243.     menu_bar(menuobj, 0);        /* erase menu bar */
  244.  
  245. punt:
  246.  
  247.     wind_delete(wi_handle);
  248.     v_clsvwk(handle);
  249.     appl_exit();
  250. }
  251.  
  252.  
  253. /*
  254.  * Get a single event, process it, and return.
  255.  *
  256.  */
  257. domulti(){
  258.     int event;
  259.     
  260.     event = evnt_multi(MU_MESAG,
  261.             1,1,butdown,
  262.             0,0,0,0,0,
  263.             0,0,0,0,0,
  264.             msgbuff,0,0,&mx,&my,&ret,&ret,&keycode,&ret);
  265.  
  266.     if (event & MU_MESAG) {
  267.         wind_update(TRUE);
  268.     switch (msgbuff[0]) {
  269.         case WM_REDRAW:
  270.         do_redraw(msgbuff[4],msgbuff[5],msgbuff[6],msgbuff[7]);
  271.         break;
  272.  
  273.         case MN_SELECTED:
  274.             BEE_MOUSE;
  275.         switch(msgbuff[3]) {
  276.             case MNDISK:
  277.             switch (msgbuff[4]) {
  278.                 case DIPART:
  279.                     if ((needscan)&&(rescan(0,2) == ERROR))    {
  280.                         break;    /* don't report medium changed */
  281.                     }
  282.                     needscan = FALSE;
  283.                     dodipart(-1, NULL, NULL);
  284.                     break;
  285.                 default:        break;
  286.             }
  287.             break;
  288.  
  289.             case MNFILE:
  290.             switch (msgbuff[4]) {
  291.                 case FIQUIT:
  292.                 running = 0;
  293.                 break;
  294.  
  295.                 default:
  296.                 break;
  297.             }
  298.             break;
  299.             
  300.             case MNDESK:
  301.             if(msgbuff[4] == DEABOUT) {
  302.                 strcpy(abtdial[ABVERSN].ob_spec, "HDX Patch Version 5.03");
  303.                  abtdial[ABOK].ob_state = NORMAL;
  304.                 execform(abtdial);
  305.             }
  306.             break;        /* "cannot happen" */
  307.         }
  308.  
  309.         menu_tnormal(menuobj, msgbuff[3], 1);    /* back to normal */
  310.             ARROW_MOUSE;
  311.         break;
  312.         
  313.         case WM_NEWTOP:
  314.         case WM_TOPPED:
  315.         wind_set(wi_handle, WF_TOP, 0, 0, 0, 0);
  316.         break;
  317.  
  318.         case WM_CLOSED:
  319.         running = FALSE;
  320.         break;
  321.  
  322.         default:
  323.         break;
  324.     }
  325.     wind_update(FALSE);
  326.     }
  327. }
  328.  
  329.  
  330. /*
  331.  * Default partition name (no "pt" entry).
  332.  */
  333. #define    DEF_PARTNAME    "4-6-10"
  334.  
  335.  
  336.  
  337. /*
  338.  * Handle [PARTITION] item;
  339.  * if `xdev' is -1, throw up dialog boxes;
  340.  * if `xdev' >= 0, just partition the dev,
  341.  * using `pnam' as the partition type, 
  342.  * and `pr_id' to search for the type.
  343.  *
  344.  */
  345. dodipart(xdev, pnam, hsize)
  346. int xdev;
  347. char *pnam;
  348. long hsize;
  349. {
  350.     int dev, i, ret =OK;
  351.     char *s;
  352.     char bs[512];
  353.     PART *pinfo;
  354.     long disksiz;
  355.     int mask = 0x0001;
  356.  
  357.  
  358.     if (xdev < 0) {
  359.     tformat = FALSE;
  360.     if ((dev = gphysdev()) < 0) {
  361.         return BAILOUT;
  362.     }
  363.     /*
  364.      * Let the user edit/pick partitions.
  365.      */
  366.      if (sfigpart(bs, dev, (PART *)&pinfo) != OK)    {
  367.         if (pinfo > 0)    Mfree(pinfo);
  368.            return BAILOUT;
  369.      }
  370.  
  371.     }
  372.  
  373.     /* For REAL!! */
  374.     dsplymsg(partmsg);
  375.     
  376.     
  377.     /* Lay out partition headers */
  378.     if (spheader(dev, &pinfo[0]) != OK) {
  379.         ret = ERROR;
  380.         goto partend;
  381.     }
  382.     
  383.     /* Partition the device with parameters given in pinfo */
  384.     if (stlaybs(dev, &pinfo[0]) != OK)
  385.         ret = ERROR;
  386.     else
  387.         ret = OK;
  388.         
  389.     pnf = 1;        /* set the flag to just doing the partition */
  390. partend:
  391.     inipart(pinfo, npart);
  392.     if (pinfo > 0)    Mfree(pinfo);
  393.     erasemsg();
  394.     return (ret);
  395. }
  396.  
  397.  
  398.  
  399. /*
  400.  * Setup partitions on the disk;
  401.  * write boot sectors and zero FATs and root directories.
  402.  *
  403.  */
  404. stlaybs(physdev, pinfo)
  405. int physdev;
  406. register PART *pinfo;
  407. {
  408.     int i, ret;
  409.     SECTOR nsect;
  410.     char *devno="X";
  411.     long ndirs;
  412.     UWORD fatsiz;
  413.     BOOT *bs;
  414.     extern long cell();
  415.     char *buf1;
  416.     long size, remsect;
  417.     long datsect;
  418.     long datclst; 
  419.     long fatclst;
  420.     long entsect;
  421.  
  422.     /* SCAN_BS: pinfo is for scan() and laybs() use */
  423.     if (ext != NO_EXT)    sortpart(pinfo, SCAN_BS);    
  424.  
  425.     for (i = 0; i < npart; ++i, ++pinfo) {
  426.         
  427.         /* don't care if partition does not exist */
  428.         if (!(pinfo->p_flg & P_EXISTS)) {
  429.             return OK;
  430.         }
  431.  
  432.     /* estimat the bps */
  433.     /* MAXSECT = 16MB - 8 */
  434.     bps = cell((pinfo->p_siz-7)*BPS, (long)MAXSECT);
  435.  
  436.     /* the real bps */
  437.     bps = BPS * n2power((UWORD)cell(bps, (long)BPS));
  438.     ratio = bps / BPS;
  439.     nsect = pinfo->p_siz / ratio;
  440.  
  441.     size = (long)BPS * ratio;
  442.  
  443.     /*
  444.      * Compute root directory size
  445.      * 256 entries, plus fudge on devs > 10Mb
  446.      */
  447.     if (pinfo->p_siz < 0x5000L) ndirs = NUMEN;
  448.     else ndirs = nsect / 80;    /* 1 dir entry per 80 sectors */
  449.     /* round to nearest sector */
  450.     ndirs = (ndirs + ((UWORD)bps/BPDIR - 1)) & ~((UWORD)bps/BPDIR - 1);    
  451.  
  452.     /*--------------------------------------------------------------*
  453.      * Compute FAT size                        *
  454.      *                                *
  455.      * Num entries to map the entire partition            *
  456.      *    = partition's size in clusters                *
  457.      *    = partition's size in sectors / spc            *
  458.      *                                *
  459.      * Num entries in FAT                        *
  460.      *    = Num entries to map partition + reserved entries    *
  461.      *    = (partition's size in sectors / spc) + 2        *
  462.      *                                *
  463.      * Num sectors FAT occupies                    *
  464.      *    = Num entries in FAT / Num entries of FAT per sector    *
  465.      *    = Num entries in FAT / (bps / 2)    <16-bit FAT>    *
  466.      *    = ((partition's size in sectors / spc) + 2) / (bps/2) + 1    *
  467.      *                        <+1 to round up>    *
  468.      *--------------------------------------------------------------*/
  469.     fatsiz = ((((nsect / SPC) + 2) * 2) / bps) + 1;/*bps ?? 512 or 1024*/
  470.  
  471.     /* Apr-23-93 jye: To fixed the same bug in the Gemdos.
  472.     /* # of sectors in datas:  
  473.      *                 datsect   = nsect - boot - 2*fatsiz - size of dir 
  474.      *                           = nsect-boot-2*fatsiz-(ndirs*32)/bps
  475.      * # of clusters in datas: 
  476.      *                datclst      = # of sectors in datas / SPC 
  477.      * # of clusters(entries) in Fat: 
  478.      *                fatclst   = fatsiz * (bps/2)
  479.      * # of sectors need in fat talbe for datclst:
  480.      *                entsect   = datclst / (bps/2)
  481.      * # of sectors need to remodify to 0xffff:
  482.      *                remsect   = fatsiz - entsect
  483.      */
  484.  
  485.     datsect = nsect - 1 - 2*fatsiz - (ndirs*32)/bps;
  486.     datclst = datsect / SPC;
  487.     fatclst = fatsiz * (bps/2);
  488.     entsect = datclst / (bps/2);
  489.     remsect = (fatsiz - entsect)*size;
  490.  
  491.  
  492.     /* # of sectors need to remodify to 0xffff */
  493.     if ((buf1 = (char *)Malloc(remsect)) <= 0)    {
  494.         err(nomemory);
  495.         if (buf1 > 0) Mfree((long)buf1);
  496.         return ERROR;
  497.     }
  498.  
  499.     /* 
  500.      * Apr-23-93 jye: To fixed the write over to next partitiona in the Gemdos  
  501.      *                  , here just set those entries in Fat table, which don't
  502.      *                  correspond to the availble date sectors in the partition.
  503.      *                  The pointers should be:
  504.      *                      p_st+(boot+datclst/(bps/2))*ratio and 
  505.      *                    p_st+(boot+fatsiz+datclst/(bps/2))*ratio 
  506.      */
  507.     if ((ret = rdsects(physdev, (UWORD)(remsect/BPS), buf1, 
  508.                      (SECTOR)pinfo->p_st+(1+datclst/(bps/2))*ratio)) != OK) {
  509.         if (tsterr(ret) != OK)
  510.             err(bootwrit);
  511.         return ERROR;
  512.     }
  513.     /* fill the last sectors of FAT start at last entry with the 0xffff */
  514.     /* +2 is for two reserved entries in the fat table */
  515.     fillfat(buf1, ((datclst%(bps/2))+2)*2, remsect, 0xffff);
  516.     if ((ret = wrsects(physdev,(UWORD)(remsect/BPS),buf1,
  517.                      (SECTOR)pinfo->p_st+(1+datclst/(bps/2))*ratio) != OK) ||
  518.         (ret = wrsects(physdev,(UWORD)(remsect/BPS),buf1,
  519.              (SECTOR)pinfo->p_st+(1+fatsiz+datclst/(bps/2))*ratio) != OK)) {
  520.         if (tsterr(ret) != OK)
  521.             err(bootwrit);
  522.         return ERROR;
  523.     }
  524.     /* Apr-23-93 jye: Add above codes to fix the Gemdos over write next
  525.      *                   partition.
  526.      */
  527.  
  528.              
  529.         if (buf1 > 0) Mfree((long)buf1);
  530.     }
  531.     return OK;
  532. }
  533.  
  534.  
  535.  
  536.  
  537. /*
  538.  * Translate unit number to tree index.
  539.  *
  540.  */
  541. static int physxlat[] = {
  542.     UNIT0, UNIT1, UNIT2, UNIT3
  543. };
  544.  
  545. static int physid[] = {
  546.     DRVID0, DRVID1, DRVID2, DRVID3
  547. };
  548.  
  549. #define ROLL1 1            /* move the bar one step */
  550. #define ROLL4 4            /* move the bar four steps */
  551.  
  552. /*
  553.  * Get physical device#,
  554.  * return devno or -1.
  555.  *
  556.  */
  557. gphysdev()
  558.  
  559. {
  560.     int xrun = 1, tpdev=0;
  561.     int index=0, i, ret;
  562.  
  563.     linkdev();            /* link all live devices into a list */
  564.     if (tformat)    {    /* when format, enable all devices in dialog box */
  565.         if ((spscsixst)    || (atexst)) { /* sparrow or notebook */
  566.             ndevs = 9;
  567.             tpdev = 8;
  568.         } else if (ttscsi) {
  569.             ndevs = 16;
  570.         } else { /* if ((!ttscsi) && (!noacsi))     Mega ST */
  571.             ndevs = 8;
  572.         }
  573.     }
  574.     /* set form for first display */
  575.     physdial[PHYSOK].ob_state = NORMAL;
  576.     physdial[PHYSCN].ob_state = NORMAL;
  577.     physdial[SLBOX].ob_y = 0;
  578.     if (ndevs <= 4)    {
  579.         physdial[SLBOX].ob_height = physdial[SLTRK].ob_height;
  580.     } else {
  581.         physdial[SLBOX].ob_height = physdial[SLTRK].ob_height / (ndevs/4.0);
  582.     }
  583.     for (i=0; i < 4; i++)    {
  584.         physdial[physxlat[i]].ob_state = NORMAL;
  585.         physdial[physid[i]].ob_state = NORMAL;
  586.     }
  587.     ok2draw = 0;
  588.     drawdev(index);    /* draw the devices into the dialog box */
  589.     ARROW_MOUSE;
  590.     dsplymsg(physdial);
  591.     ++ok2draw;
  592.     while (xrun)     {
  593.         switch (ret=form_do(physdial, -1))     {
  594.             case PHYSOK:xrun = 0;
  595.                         break;
  596.             case PHYSCN:xrun = 0;            /* return */
  597.                         break;
  598.             case SLTRK: if (ndevs > 5)    {
  599.                             scrupdn(ROLL4, &index);
  600.                         }
  601.                         break;
  602.             case SLUP:  if (index != 0)    {
  603.                             scrupdn(ROLL1, &index);
  604.                         }
  605.                         break;
  606.             case SLDN:  if ((index < 12) && (index+4 < ndevs))    {
  607.                             scrupdn(ROLL1, &index);
  608.                         }
  609.                         break;
  610.             case SLBOX: if (ndevs > 5)    {
  611.                             slidebox(physdial, &index);
  612.                         }
  613.                         break;
  614.             case DRVID0:physdial[UNIT0].ob_state = SELECTED;
  615.                        objc_draw(physdial,UNIT0, MAX_DEPTH, 0, 0, wdesk, hdesk);
  616.                         break;;
  617.             case DRVID1:physdial[UNIT1].ob_state = SELECTED;
  618.                        objc_draw(physdial,UNIT1, MAX_DEPTH, 0, 0, wdesk, hdesk);
  619.                         break;;
  620.             case DRVID2:physdial[UNIT2].ob_state = SELECTED;
  621.                        objc_draw(physdial,UNIT2, MAX_DEPTH, 0, 0, wdesk, hdesk);
  622.                         break;;
  623.             case DRVID3:physdial[UNIT3].ob_state = SELECTED;
  624.                        objc_draw(physdial,UNIT3, MAX_DEPTH, 0, 0, wdesk, hdesk);
  625.                         break;;
  626.             case UNIT0:physdial[DRVID0].ob_state = SELECTED;
  627.                        objc_draw(physdial,DRVID0, MAX_DEPTH, 0, 0, wdesk, hdesk);
  628.                         break;;
  629.             case UNIT1:physdial[DRVID1].ob_state = SELECTED;
  630.                        objc_draw(physdial,DRVID1, MAX_DEPTH, 0, 0, wdesk, hdesk);
  631.                         break;;
  632.             case UNIT2:physdial[DRVID2].ob_state = SELECTED;
  633.                        objc_draw(physdial,DRVID2, MAX_DEPTH, 0, 0, wdesk, hdesk);
  634.                         break;;
  635.             case UNIT3:physdial[DRVID3].ob_state = SELECTED;
  636.                        objc_draw(physdial,DRVID3, MAX_DEPTH, 0, 0, wdesk, hdesk);
  637.                         break;;
  638.           }
  639.       }
  640.  
  641.   /*
  642.    * Draw shrinking box and cleanup the screen;
  643.    * return thing that caused our exit.
  644.    */
  645.     erasemsg();
  646.  
  647.     if (ret == PHYSCN)    {
  648.         return ERROR;
  649.     }
  650.     /* search for the selected unit */
  651.     for (i=0; i < 4; i++)    {
  652.         if (physdial[physxlat[i]].ob_state & SELECTED)    {
  653.             if (tformat)    {
  654.                 return(index+tpdev+i);
  655.             } else {
  656.                 return(devid[index+i].dev);
  657.             }
  658.         }
  659.     }
  660.     return ERROR;
  661. }
  662.  
  663. /* draw the select devices dialog box for the format operation */
  664.  
  665. fdrawdev(index)
  666. int index;
  667. {
  668.  
  669.     int i, st=0;
  670.  
  671.     if ((spscsixst)    || (atexst))    {
  672.         st = 8;
  673.     }
  674.     
  675.     for (i=0; i < 4; i++)    {
  676.         if (i+index+st < 8)    {
  677.               (physdial[physxlat[i]].ob_spec)->te_ptext = &drvid[19+i+index][0];
  678.         } else if (i+index+st < 16)    {
  679.         (physdial[physxlat[i]].ob_spec)->te_ptext = &drvid[27+i+index+st-8][0];
  680.         } else {
  681.             (physdial[physxlat[i]].ob_spec)->te_ptext = &drvid[35][0];
  682.         }
  683.         physdial[physxlat[i]].ob_state = NORMAL;
  684.         physdial[physid[i]].ob_state = NORMAL;
  685.         if (i+index+st == 16)    {    /* it is sparrow */
  686.             (physdial[physid[i]].ob_spec)->te_ptext = &drvid[i+index+st][0];
  687.         } else if (livedevs[i+index+st])    {
  688.             if (idevs[i+index+st])    {
  689.                 (physdial[physid[i]].ob_spec)->te_ptext = &drvid[i+index+st][0];
  690.             } else {
  691.                 (physdial[physid[i]].ob_spec)->te_ptext = &drvid[17][0];
  692.             }
  693.         } else {
  694.             if (idevs[i+index+st])    {
  695.                 (physdial[physid[i]].ob_spec)->te_ptext = &drvid[i+index+st][0];
  696.             } else {
  697.                 (physdial[physid[i]].ob_spec)->te_ptext = &drvid[18][0];
  698.             }
  699.         }
  700.         if (ok2draw)    {
  701.             objc_draw(physdial,physxlat[i], MAX_DEPTH, 0, 0, wdesk, hdesk);
  702.             objc_draw(physdial,physid[i], MAX_DEPTH, 0, 0, wdesk, hdesk);
  703.         }
  704.     }
  705. }
  706.     
  707. /* draw the select devices dialog box for the partition operation */
  708.  
  709. drawdev(index)
  710. int index;
  711. {
  712.  
  713.     int i, j;
  714.  
  715.     if (tformat)    {
  716.         fdrawdev(index);
  717.         return OK;
  718.     }
  719.  
  720.     for (i=0; i < 4; i++)    {
  721.         (physdial[physxlat[i]].ob_spec)->te_ptext = &drvid[36][0];
  722.         (physdial[physid[i]].ob_spec)->te_ptext = &drvid[36][0];
  723.         if (devid[i+index].flg)    {
  724.                physdial[physxlat[i]].ob_state = NORMAL;
  725.                physdial[physid[i]].ob_state = NORMAL;
  726.             j = devid[i+index].dev;
  727.             if (j < 8)    {
  728.                 (physdial[physxlat[i]].ob_spec)->te_ptext = &drvid[19+j][0];
  729.             } else if (j < 16)    {
  730.                 (physdial[physxlat[i]].ob_spec)->te_ptext = &drvid[27+j-8][0];
  731.             } else {
  732.                 (physdial[physxlat[i]].ob_spec)->te_ptext = &drvid[35][0];
  733.             }
  734.             (physdial[physid[i]].ob_spec)->te_ptext = devid[i+index].id;
  735.         } else {
  736.             physdial[physxlat[i]].ob_state = DISABLED;
  737.             physdial[physid[i]].ob_state = DISABLED;
  738.         }
  739.         if (ok2draw)    {
  740.             objc_draw(physdial,physxlat[i], MAX_DEPTH, 0, 0, wdesk, hdesk);
  741.             objc_draw(physdial,physid[i], MAX_DEPTH, 0, 0, wdesk, hdesk);
  742.         }
  743.     }
  744. }
  745.  
  746. scrupdn(roll, index)
  747. int roll;
  748. int *index;
  749.  
  750. {
  751.      int gr_mkmx, gr_mkmy;
  752.     int gr_mkmstate, gr_mkkstate;
  753.     int barht, barx, bary;
  754.     int eptx, epty, eptht;
  755.  
  756.     barht = physdial[SLTRK].ob_height;
  757.     eptht = physdial[SLBOX].ob_height;
  758.     graf_mkstate(&gr_mkmx, &gr_mkmy, &gr_mkmstate, &gr_mkkstate);
  759.     objc_offset(physdial, SLBOX, &eptx, &epty);
  760.     objc_offset(physdial, SLTRK, &barx, &bary);
  761.     /* check which part of bar was clicked */
  762.     if (gr_mkmy > (epty+eptht))    {    /* low part of bar was clicked */
  763.         if (roll == ROLL4)    {
  764.             if ((*index+5 >= ndevs) || (eptht > (bary+barht-epty-eptht)))    {
  765.                 physdial[SLBOX].ob_y = barht - eptht;
  766.                 *index = ndevs - 4;    /* the last 4 to display */
  767.             } else if (*index+4 < ndevs)    {
  768.                 physdial[SLBOX].ob_y += eptht;
  769.                 *index += 4;
  770.             }
  771.         } else {    /* ROLL1 */
  772.             if ((*index+5 >= ndevs)||((barht/ndevs)>(bary+barht-epty-eptht))){
  773.                 physdial[SLBOX].ob_y = barht - eptht;
  774.                 *index = ndevs - 4;    /* the last 4 to display */
  775.             } else {
  776.                 physdial[SLBOX].ob_y += barht / ndevs;
  777.                 *index += 1;
  778.             }
  779.         }
  780.     } else if (gr_mkmy < epty)    {    /* upper part of bar was clicked */
  781.         if (roll == ROLL4)    {
  782.             if ((eptht > (epty - bary)) || (*index <= 4))    {
  783.                 physdial[SLBOX].ob_y = 0;
  784.                 *index = 0;
  785.             } else {
  786.                 physdial[SLBOX].ob_y -= eptht;
  787.                 *index -= 4;
  788.             }
  789.         } else {
  790.             if (*index <= 1)    {
  791.                 physdial[SLBOX].ob_y = 0;
  792.                 *index = 0;
  793.             } else {
  794.                 physdial[SLBOX].ob_y -= barht / ndevs;
  795.                 *index -= 1;
  796.             }
  797.         }
  798.     } else {
  799.       return OK;
  800.     }
  801.     objc_draw(physdial,SLTRK, MAX_DEPTH, 0, 0, wdesk, hdesk);
  802.     drawdev(*index);
  803. }
  804.  
  805.  
  806. slidebox(tree, index)
  807.  
  808. OBJECT *tree;
  809. int *index;
  810.  
  811. {
  812.     int gr_wreturn, eptatmax;
  813.     int ind, tmp;
  814.  
  815.     ind = ndevs - 4;
  816.     eptatmax = tree[SLTRK].ob_height - tree[SLBOX].ob_height;
  817.     gr_wreturn = graf_slidebox(tree, SLTRK, SLBOX, 1);
  818.     tmp = (ind * gr_wreturn) / 1000;
  819.     if (tmp == *index)    {    /* slide box is in the same place */
  820.         return OK;    
  821.     } else {
  822.         *index = tmp;
  823.     }
  824.     if (*index+4 > ndevs)    {
  825.         *index = ndevs-4;
  826.     } 
  827.     tree[SLBOX].ob_y = (eptatmax * (*index)) / ind;
  828.     objc_draw(tree, SLTRK, MAX_DEPTH, 0, 0, wdesk, hdesk);
  829.     drawdev(*index);
  830. }
  831.  
  832.  
  833.  
  834. /* put the live device into a list */
  835.  
  836. linkdev()
  837. {
  838.  
  839.     int i, j=0;
  840.  
  841.     for (i=0; i<16; i++)    {
  842.         devid[i].flg = 0;
  843.         devid[i].id = &drvid[18][0];
  844.         if (livedevs[i])    {
  845.             devid[j].flg = P_EXISTS;
  846.             devid[j].dev = i;
  847.             if (idevs[i])    {
  848.                 devid[j++].id = &drvid[i][0];
  849.             } else {
  850.                 devid[j++].id = &drvid[17][0];
  851.             }
  852.         } else if (idevs[i])    {
  853.             devid[j].flg = 2;
  854.             devid[j].dev = i;
  855.             devid[j++].id = &drvid[i][0];
  856.         }
  857.     }
  858.     if ((spscsixst) || (atexst))    {
  859.         devid[j].flg = P_EXISTS;
  860.         devid[j].dev = i;
  861.         devid[j++].id = &drvid[i][0];
  862.     }
  863.  
  864.     ndevs = j;    /* number of live devices */
  865.  
  866. }
  867.  
  868.  
  869.  
  870.  
  871. /*
  872.  * Open virtual workstation.
  873.  *
  874.  */
  875. open_vwork()
  876. {
  877.     int i;
  878.  
  879.     for (i = 0; i < 10;)
  880.     work_in[i++] = 1;
  881.     work_in[10] = 2;
  882.     handle = phys_handle;
  883.     v_opnvwk(work_in, &handle, work_out);
  884. }
  885.  
  886.  
  887. /*
  888.  * Find and redraw all clipping rectangles
  889.  *
  890.  */
  891. do_redraw(xc, yc, wc, hc)
  892. int xc, yc, wc, hc;
  893. {
  894.     GRECT t1, t2;
  895.     int temp[4];
  896.  
  897.     hide_mouse();
  898.     t2.g_x=xc;
  899.     t2.g_y=yc;
  900.     t2.g_w=wc;
  901.     t2.g_h=hc;
  902.     vsf_interior(handle, 1);
  903.     vsf_color(handle, 0);
  904.     wind_get(wi_handle, WF_FIRSTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  905.     while (t1.g_w && t1.g_h) {
  906.     if (rc_intersect(&t2, &t1)) {
  907.         set_clip(t1.g_x, t1.g_y, t1.g_w, t1.g_h);
  908.         temp[0] = xwork;
  909.         temp[1] = ywork;
  910.         temp[2] = xwork + wwork - 1;
  911.         temp[3] = ywork + hwork - 1;
  912.         v_bar(handle, temp);
  913.     }
  914.     wind_get(wi_handle, WF_NEXTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  915.     }
  916.  
  917.     show_mouse();
  918. }
  919.  
  920.  
  921. /*
  922.  * Hide the mouse.
  923.  *
  924.  */
  925. hide_mouse()
  926. {
  927.     if (!hidden) {
  928.     graf_mouse(M_OFF, 0L);
  929.     hidden = TRUE;
  930.     }
  931. }
  932.  
  933.  
  934. /*
  935.  * Show the mouse.
  936.  *
  937.  */
  938. show_mouse() 
  939. {
  940.     if (hidden) {
  941.     graf_mouse(M_ON, 0L);
  942.     hidden = FALSE;
  943.     }
  944. }
  945.  
  946.  
  947. /*
  948.  * Set clipping rectangle.
  949.  *
  950.  */
  951. set_clip(x, y, w, h)
  952. int x, y, w, h;
  953. {
  954.     int clip[4];
  955.  
  956.     clip[0] = x;
  957.     clip[1] = y;
  958.     clip[2] = x + w;
  959.     clip[3] = y + h;
  960.     vs_clip(handle, 1, clip);
  961. }
  962.  
  963.  
  964. /*
  965.  * "Execute" form,
  966.  * return thingy that caused the exit.
  967.  *
  968.  */
  969. execform(tree)
  970. OBJECT tree[];
  971. {
  972.     int thingy;
  973.  
  974.     ARROW_MOUSE;
  975.     dsplymsg(tree);
  976.     thingy = form_do(tree, 0);
  977.     erasemsg();
  978.     BEE_MOUSE;
  979.     return thingy;
  980. }
  981.  
  982.  
  983. /*
  984.  *  Display a dialogue box on the screen.
  985.  *    Input:
  986.  *        tree - object tree for dialogue box to be displayed.
  987.  *    Output:
  988.  *        formw, formh, sx, sy, lx, ly - dimensions of box.
  989.  */
  990. dsplymsg(tree)
  991. OBJECT *tree;
  992. {
  993.     form_center(tree,&lx, &ly, &formw, &formh);
  994.  
  995.     
  996.     form_dial(1, 0, 0, 0, 0, lx, ly, formw, formh);
  997.     objc_draw(tree, 0, MAX_DEPTH, 0, 0, wdesk, hdesk);
  998. }
  999.  
  1000.  
  1001. /*
  1002.  *  Erase a dialogue box from the screen.
  1003.  *    Input:
  1004.  *        formw, formh, sx, sy, lx, ly - dimensions of box.
  1005.  */
  1006. erasemsg()
  1007. {
  1008.     form_dial(3, 0, 0, 0, 0, lx, ly, formw, formh);
  1009. }
  1010.  
  1011.  
  1012.  
  1013.  
  1014. /*
  1015.  * Fill the buffer with 0xffff start from giving pointer
  1016.  * to the end of buffer.
  1017.  */
  1018.  
  1019. fillfat(buf, start, size, pattern)
  1020. char *buf;
  1021. long start;
  1022. long size;
  1023. int pattern;
  1024. {
  1025.     long i;    /* index */
  1026.     
  1027.     for (i = start; i < size; i += 2)
  1028.     *(int *)&buf[i] = pattern;
  1029. }
  1030.  
  1031.  
  1032.  
  1033.  
  1034. /*
  1035.  *  Get size of the Bad Sector List (in sectors)
  1036.  *    Input:
  1037.  *        pdev - physical unit BSL belongs to.
  1038.  *    Return:
  1039.  *        number of sectors BSL occupies.
  1040.  */
  1041. long 
  1042. gbslsiz(pdev) 
  1043. int pdev;    /* physical device number */
  1044. {
  1045.     char bs[512];    /* boot sector image */
  1046.     UWORD  ret;
  1047.     
  1048.        if ((ret = getroot(pdev, bs, (SECTOR)0)) != 0) {
  1049.            if (tsterr(ret) == OK)
  1050.             return MDMERR;
  1051.         else return ERROR;
  1052.        }
  1053.        if (((RSECT *)(bs + 0x200 - sizeof(RSECT)))->bsl_st != STBSL)
  1054.            return 0L;
  1055.        return(((RSECT *)(bs + 0x200 - sizeof(RSECT)))->bsl_cnt);
  1056. }
  1057.  
  1058.  
  1059.  
  1060.  
  1061.  
  1062.